/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * Principal.java
 *
 * Created on 14/10/2013, 04:35:18 PM
 */

package proyectoarboles;

import java.awt.Graphics;
import java.awt.Point;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JOptionPane;

/**
 *
 * @author Andres Mauricio Ruiz, Luis Eduardo Ramirez
 */
public class Principal extends javax.swing.JFrame{

    private Point inicioArrastre;
    private List<Line2D> lineas = new ArrayList<>();
    private Nodo nodoArbol;
    private List<String> listaLetras=new ArrayList<>();
    private int contador=0;
    //Variables para pintar el arbol
    private Arbol arbol2D;
    private int alturaArbol;
    private int numeroNodos;
    private int alto=0;
    private int ancho=0;

    /** Creates new form Principal */
    public Principal() {
       initComponents();
       arbol2D=new Arbol();
    }

    /**
     * Método para dibujar el arbol en el panel del arbol correspondiente
     * @param graphics
     */
    private void dibujarArbol(Graphics graphics){
        Punto centro = new Punto(250,100);
        //Espacio entre nodos horizontales basado en el número de nodos
        int espacioX = ((300 - (Constantes.BORDE_SEPARADOR * 2)) / numeroNodos);
        //Espacio entre nodos verticales basado en la profundidad
        int espacioY = ((200 - (Constantes.BORDE_SEPARADOR * 2) - Constantes.TAMANIO_BARRA) / alturaArbol);
        //Iniciamos pintanto el arbol desde la izquierda y desde la cordenada superior en Y
        int izquierdaX = centro.coordenadaX - ((espacioX * numeroNodos) / 2);
        int superiorY = centro.coordenadaY - ((espacioY * alturaArbol) / 2);
        int dimensionCaja = getDimensionCaja(espacioX,espacioY);
        izquierdaX += (dimensionCaja / 4);
        arbol2D.dibujarArbol(graphics,izquierdaX,superiorY,dimensionCaja,espacioX,espacioY);
    }

    /**
     * Método para dibujar el plano
     * @param graphics
     */
    private void dibujarPlano(Graphics graphics){
        //Creamos los puntos para dibujar el rectangulo principal, desde el punto (0,0)
        //hasta punto(Width,Height) del panel
        Punto puntoSuperiorIzquierdo = new Punto(Constantes.BORDE_RELLENO,Constantes.BORDE_RELLENO);
        Punto puntoDimensionPlano = new Punto(ancho,alto);
        //Dibujamos el plano en el panel del plano con letras
        Plano plano=new Plano();
        graphics.drawRect(puntoSuperiorIzquierdo.coordenadaX, puntoSuperiorIzquierdo.coordenadaY,
                puntoDimensionPlano.coordenadaX, puntoDimensionPlano.coordenadaY);
        plano.dibujarPlanoPorNodo(graphics, arbol2D.getPrincipal(), puntoSuperiorIzquierdo, puntoDimensionPlano);
    }

    /**
     * Método para calcular la dimension de la caja que pinta los nodos hoja
     * @param x
     * @param y
     * @return
     */
    private int getDimensionCaja(int x, int y){
        int tamanio = x;										
        if(x > y){												
            tamanio = y;
        }
        tamanio += 12;
        return tamanio / 2;
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanelPlano = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jButtonNuevo = new javax.swing.JButton();
        jPanelArbol = new javax.swing.JPanel();
        jPanelLetra = new javax.swing.JPanel();
        jButton1 = new javax.swing.JButton();
        jLabel3 = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();
        jTextFieldAncho = new javax.swing.JTextField();
        jTextFieldAlto = new javax.swing.JTextField();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setBackground(new java.awt.Color(-1,true));
        setResizable(false);

        jPanelPlano.setBackground(new java.awt.Color(-1,true));
        jPanelPlano.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(-16777216,true)));
        jPanelPlano.setName("jPanelPlano"); // NOI18N
        jPanelPlano.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                jPanelPlanoMousePressed(evt);
            }
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                jPanelPlanoMouseReleased(evt);
            }
        });
        jPanelPlano.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                jPanelPlanoMouseDragged(evt);
            }
        });

        javax.swing.GroupLayout jPanelPlanoLayout = new javax.swing.GroupLayout(jPanelPlano);
        jPanelPlano.setLayout(jPanelPlanoLayout);
        jPanelPlanoLayout.setHorizontalGroup(
            jPanelPlanoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 398, Short.MAX_VALUE)
        );
        jPanelPlanoLayout.setVerticalGroup(
            jPanelPlanoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 161, Short.MAX_VALUE)
        );

        jLabel1.setFont(new java.awt.Font("Dialog", 0, 24));
        jLabel1.setText("Plano");
        jLabel1.setName("jLabel1"); // NOI18N

        jLabel2.setFont(new java.awt.Font("Dialog", 0, 24));
        jLabel2.setText("Árbol");
        jLabel2.setName("jLabel2"); // NOI18N

        jButtonNuevo.setText("Nuevo Plano");
        jButtonNuevo.setName("jButtonNuevo"); // NOI18N
        jButtonNuevo.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonNuevoActionPerformed(evt);
            }
        });

        jPanelArbol.setBackground(new java.awt.Color(-1,true));
        jPanelArbol.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(-16777216,true)));
        jPanelArbol.setName("jPanelArbol"); // NOI18N

        javax.swing.GroupLayout jPanelArbolLayout = new javax.swing.GroupLayout(jPanelArbol);
        jPanelArbol.setLayout(jPanelArbolLayout);
        jPanelArbolLayout.setHorizontalGroup(
            jPanelArbolLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 548, Short.MAX_VALUE)
        );
        jPanelArbolLayout.setVerticalGroup(
            jPanelArbolLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 525, Short.MAX_VALUE)
        );

        jPanelLetra.setBackground(new java.awt.Color(-1,true));
        jPanelLetra.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(-16777216,true)));
        jPanelLetra.setName("jPanelLetra"); // NOI18N

        javax.swing.GroupLayout jPanelLetraLayout = new javax.swing.GroupLayout(jPanelLetra);
        jPanelLetra.setLayout(jPanelLetraLayout);
        jPanelLetraLayout.setHorizontalGroup(
            jPanelLetraLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 398, Short.MAX_VALUE)
        );
        jPanelLetraLayout.setVerticalGroup(
            jPanelLetraLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 356, Short.MAX_VALUE)
        );

        jButton1.setText("Invertir");
        jButton1.setName("jButton1"); // NOI18N
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        jLabel3.setText("Ancho");
        jLabel3.setName("jLabel3"); // NOI18N

        jLabel4.setText("Alto");
        jLabel4.setName("jLabel4"); // NOI18N

        jTextFieldAncho.setName("jTextFieldAncho"); // NOI18N

        jTextFieldAlto.setName("jTextFieldAlto"); // NOI18N

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addGap(10, 10, 10)
                        .addComponent(jButton1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(jButtonNuevo)
                        .addGap(88, 88, 88))
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(jPanelPlano, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jPanelLetra, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(10, 10, 10)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanelArbol, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addGap(229, 229, 229)
                .addComponent(jLabel1)
                .addGap(44, 44, 44)
                .addComponent(jLabel3)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jTextFieldAncho, javax.swing.GroupLayout.PREFERRED_SIZE, 52, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(jLabel4)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jTextFieldAlto, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 171, Short.MAX_VALUE)
                .addComponent(jLabel2)
                .addGap(235, 235, 235))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel2)
                    .addComponent(jLabel1)
                    .addComponent(jLabel4)
                    .addComponent(jTextFieldAlto, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel3)
                    .addComponent(jTextFieldAncho, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jPanelPlano, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jPanelLetra, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addComponent(jPanelArbol, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButtonNuevo)
                    .addComponent(jButton1))
                .addGap(21, 21, 21))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jPanelPlanoMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jPanelPlanoMousePressed
        // TODO add your handling code here:
      //inicioArrastre = new Point(evt.getX(), evt.getY());
      if(!jTextFieldAlto.getText().equals("") && !jTextFieldAncho.getText().equals("")){
           try{

               alto=Integer.parseInt(jTextFieldAlto.getText());
               ancho=Integer.parseInt(jTextFieldAncho.getText());
               if(alto>jPanelLetra.getHeight()){
                   JOptionPane.showMessageDialog(rootPane, "El alto no debe superar: "+jPanelLetra.getHeight());
               }else if(ancho>jPanelLetra.getWidth()){
                   JOptionPane.showMessageDialog(rootPane, "El ancho no debe superar: "+jPanelLetra.getWidth());
               }else{
                   inicioArrastre = new Point(evt.getX(), evt.getY());
               }

           }catch(NumberFormatException n){
                System.out.println("El dato no es numerico");
           }
        }else{
           JOptionPane.showMessageDialog(rootPane, "Ingrese las cordenadas");
        }
    }//GEN-LAST:event_jPanelPlanoMousePressed

    private void jPanelPlanoMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jPanelPlanoMouseReleased
        //Variables para dibujar las lineas
        Graphics graphics=jPanelPlano.getGraphics();
        int coordenadaX=evt.getX();
        int coordenadaY=evt.getY();
        int diferenciaX=  Math.abs(inicioArrastre.x-coordenadaX);
        int diferenciaY=  Math.abs(inicioArrastre.y-coordenadaY);
        boolean seDibujaLinea=false;
        /**
         * False si es horizontal, True si es vertical
         */
        boolean orientacion=false;
       //Organizamos las coordenas para que la lineas sean totalmente rectas
        if(diferenciaX<=50){
            //Esta linea es Vertical
            coordenadaX=inicioArrastre.x;
            seDibujaLinea=true;
            orientacion=true;

        }else if(diferenciaY<=50){
            //Esta linea es Horizontal
            coordenadaY=inicioArrastre.y;
            seDibujaLinea=true;
        }
        //Se dibula la linea
        if(seDibujaLinea){
            /**
             * Creamos una linea desde le punto menor al punto mayor
             */
            Line2D linea = establecerLineaMayorLineaMenor(inicioArrastre.x, inicioArrastre.y, coordenadaX, coordenadaY);
            lineas.add(linea);
            /**
             * Llamamos al metodo de llenar las letras para los nodos hojas
             */
            llenarLetras();
            contador=0;
            if(nodoArbol!=null){
                /**
                 * Si el nodo raiz es diferente de null entonces borramos los nodos hijos
                 */
                borrarHoja(nodoArbol);
            }
            /**
             * Despues de verificar si la orientacion de la linea es vertical u horizontal
             * llamamos los metodos de crear nodo por X o por Y
             */
            if(orientacion){
               nodoArbol=crearNodoX(nodoArbol, linea,Constantes.LINEA_VERTICAL);
            }else{
               nodoArbol=crearNodoY(nodoArbol, linea,Constantes.LINEA_HORIZONTAL);
            }
            /**
             * Llenamos los nodos hojas
             */
            llenarHojas(nodoArbol);
            //inOrderNodo(nodoArbol);

            graphics.drawLine(inicioArrastre.x, inicioArrastre.y, coordenadaX, coordenadaY);
            Graphics graphicsArbol=jPanelArbol.getGraphics();
            //Limpiamos el panel del arbol para actualizar el dibujo
            graphicsArbol.clearRect(10, 5, jPanelArbol.getWidth()-30, jPanelArbol.getHeight()-50);
            //Dibujamos el arbol
            arbol2D.setPrincipal(nodoArbol);
            alturaArbol=arbol2D.getAlturaArbol();
            numeroNodos=arbol2D.getNumeroNodos();
            dibujarArbol(graphicsArbol);
            //Dibujamos el plano con las letras
            Graphics graphicsPlano=jPanelLetra.getGraphics();
            graphicsPlano.clearRect(10, 5, jPanelLetra.getWidth()-30, jPanelLetra.getHeight()-50);
            dibujarPlano(graphicsPlano);
        }
        
    }//GEN-LAST:event_jPanelPlanoMouseReleased
    /**
     * Metood que determina en x1 y en y1 las cordenadas menores entre x1, x2, y y1 y y2
     * @param x1
     * @param y1
     * @param x2
     * @param y2
     * @return
     */
    public Line2D establecerLineaMayorLineaMenor(int x1,int y1,int x2, int y2){
        int x1Temp;
        int x2Temp;
        if(x1>x2){
            x1Temp=x2;
            x2Temp=x1;
        }else{
            x1Temp=x1;
            x2Temp=x2;
        }

        int y1Temp;
        int y2Temp;
        if(y1>y2){
            y1Temp=y2;
            y2Temp=y1;
        }else{
            y1Temp=y1;
            y2Temp=y2;
        }

        return crearLinea(x1Temp, y1Temp, x2Temp, y2Temp);
    }
    /**
     * Metodo que recore el arbol de manera ordenada
     * @param nodo
     */
    private void inOrderNodo(Nodo nodo){

        if(nodo!=null){
            inOrderNodo(nodo.getIzquierda());
            inOrderNodo(nodo.getDerecha());
            if(nodo.getDato().equals(Constantes.LINEA_HORIZONTAL)){
                nodo.setDato(Constantes.LINEA_VERTICAL);
            }else if(nodo.getDato().equals(Constantes.LINEA_VERTICAL)){
                nodo.setDato(Constantes.LINEA_HORIZONTAL);
            }
        }
    }
    /**
     * Metodo que crea y agrupa el nodo validando sus cordenadas y ubicandolo en el arbol
     * @param nodo
     * @param valor
     * @param valorMostrar
     * @return
     */
   private Nodo crearNodoX(Nodo nodo,Object valor,String valorMostrar){


        if(nodo==null){
            nodo=new Nodo(valor,valorMostrar);
        }else{

            Line2D lineaNodo= (Line2D)nodo.getDatoLinea();
            Line2D lineaEntrada= (Line2D)valor;
            /**
             * Consultamos si la cordenada se encuentra en X1 y X2, significa que hay un corte.
             */
            if(lineaEntrada.getX1()>=lineaNodo.getX1() && lineaEntrada.getX1()<=lineaNodo.getX2() ){

                /**
                 * Si el punto de entrada en x1 es igual al punto nodo en x1 entonces miramos la orientacion de y
                 */
                if(lineaEntrada.getY1()==lineaNodo.getY1()){
                    /**
                     * Miramos para donde va X2
                     */
                    if(lineaEntrada.getY2()>lineaNodo.getY1()){
                        /**
                         * Va por derecha
                         */
                        if(nodo.getDerecha()!=null){
                            crearNodoX(nodo.getDerecha(), lineaEntrada, valorMostrar);
                        }else{
                            nodo.setDerecha(new Nodo(valor,valorMostrar));
                        }
                    }else if(lineaEntrada.getY2()<lineaNodo.getY1()){
                        /**
                         * va por izquierda
                         */
                        if(nodo.getIzquierda()!=null){
                            crearNodoX(nodo.getIzquierda(), lineaEntrada, valorMostrar);
                        }else{
                            nodo.setIzquierda(new Nodo(valor,valorMostrar));
                        }
                    }

                }
                else if(lineaEntrada.getY1() > lineaNodo.getY1()){

                   /**
                     * por izquierda
                     */
                    if(nodo.getIzquierda()!=null){
                        crearNodoX(nodo.getIzquierda(), lineaEntrada, valorMostrar);
                    }else{
                        nodo.setIzquierda(new Nodo(valor,valorMostrar));
                    }
                }else if(lineaEntrada.getY1()<lineaNodo.getY1()){
                    /**
                     * por derecha
                     */
                    if(nodo.getDerecha()!=null){
                        crearNodoX(nodo.getDerecha(), lineaEntrada, valorMostrar);
                    }else{
                        nodo.setDerecha(new Nodo(valor,valorMostrar));
                    }
                }
            }else{
                /**
                 * En caso de no encontrar corte, consultamos si la cordenada en X es mayor o menor y la ubicamos
                 */
                if(lineaEntrada.getX1()>lineaNodo.getX1()){
                    if(nodo.getDerecha()!=null){
                        crearNodoX(nodo.getDerecha(), lineaEntrada, valorMostrar);
                    }else{
                        nodo.setDerecha(new Nodo(valor,valorMostrar));
                    }
                }else if(lineaEntrada.getX1()<lineaNodo.getX1()){
                    /**
                     * por izquierda
                     */
                    if(nodo.getIzquierda()!=null){
                        crearNodoX(nodo.getIzquierda(), lineaEntrada, valorMostrar);
                    }else{
                        nodo.setIzquierda(new Nodo(valor,valorMostrar));
                    }
                }
            }

        }
        return nodo;
    }
    /**
     * Metodo que crea y agrupa el nodo validando sus cordenadas y ubicandolo en el arbol
     * @param nodo
     * @param valor
     * @param valorMostrar
     * @return
     */
    private Nodo crearNodoY(Nodo nodo,Object valor,String valorMostrar){

        if(nodo==null){
            nodo=new Nodo(valor,valorMostrar);
        }else{

            Line2D lineaNodo= (Line2D)nodo.getDatoLinea();
            Line2D lineaEntrada= (Line2D)valor;
                /**
                 * Consultamos si la cordenada se encuentra en Y1 y Y2, significa que hay un corte.
                 */
                if(lineaEntrada.getY1()>=lineaNodo.getY1() && lineaEntrada.getY1()<=lineaNodo.getY2() ){
                /**
                 * Si el punto de entrada en x1 es igual al punto nodo en x1 entonces miramos la orientacion de y
                 */
                if(lineaEntrada.getX1()==lineaNodo.getX1()){
                    /**
                     * Miramos para donde va X2
                     */
                    if(lineaEntrada.getX2()>lineaNodo.getX1()){
                        /**
                         * Va por derecha
                         */
                        if(nodo.getDerecha()!=null){
                            crearNodoY(nodo.getDerecha(), lineaEntrada, valorMostrar);
                        }else{
                            nodo.setDerecha(new Nodo(valor,valorMostrar));
                        }
                    }else if(lineaEntrada.getX2()<lineaNodo.getX1()){
                        /**
                         * va por izquierda
                         */
                        if(nodo.getIzquierda()!=null){
                            crearNodoY(nodo.getIzquierda(), lineaEntrada, valorMostrar);
                        }else{
                            nodo.setIzquierda(new Nodo(valor,valorMostrar));
                        }
                    }
                }else if(lineaEntrada.getX1() > lineaNodo.getX1()){
                    /**
                     * por derecha
                     */
                    if(nodo.getDerecha()!=null){
                        crearNodoY(nodo.getDerecha(), lineaEntrada, valorMostrar);
                    }else{
                        nodo.setDerecha(new Nodo(valor,valorMostrar));
                    }
                }else if(lineaEntrada.getX1()<lineaNodo.getX1()){
                    /**
                     * por izquierda
                     */
                    if(nodo.getIzquierda()!=null){
                        crearNodoY(nodo.getIzquierda(), lineaEntrada, valorMostrar);
                    }else{
                        nodo.setIzquierda(new Nodo(valor,valorMostrar));
                    }
                }
            }else{
                /**
                 * En caso de no encontrar corte, consultamos si la cordenada en Y es mayor o menor y la ubicamos
                 * Teniendo en cuenta que el plano es de menor a mayor se ubica de izquierda a derecha
                 */
                if(lineaEntrada.getY1()>lineaNodo.getY1()){
                    /**
                     * por izquierda
                     */
                    if(nodo.getIzquierda()!=null){
                        crearNodoY(nodo.getIzquierda(), lineaEntrada, valorMostrar);
                    }else{
                        nodo.setIzquierda(new Nodo(valor,valorMostrar));
                    }

                }else if(lineaEntrada.getY1()<lineaNodo.getY1()){
                    if(nodo.getDerecha()!=null){
                        crearNodoY(nodo.getDerecha(), lineaEntrada, valorMostrar);
                    }else{
                        nodo.setDerecha(new Nodo(valor,valorMostrar));
                    }
                }
            }
        }
        return nodo;
    }


    /**
     * Método para crear la linea del plano de corte
     * @param x1
     * @param y1
     * @param x2
     * @param y2
     * @return Shape de la forma linea con sus coordenada y dimensiones
     */
    private Line2D.Float crearLinea(int x1, int y1, int x2, int y2) {
        return new Line2D.Float(x1, y1, x2, y2);
    }

    private void jPanelPlanoMouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jPanelPlanoMouseDragged
        // TODO add your handling code here:
        ///jPanelPlano.repaint();
    }//GEN-LAST:event_jPanelPlanoMouseDragged
    /**
     * Metodo que crea un nuevo arbol y un nuevo mapa
     * @param evt
     */
    private void jButtonNuevoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonNuevoActionPerformed
        //Inicializar la variables para crear un nuevo nodo
        jPanelPlano.removeAll();
        jPanelPlano.repaint();
        jPanelArbol.removeAll();
        jPanelArbol.repaint();
        jPanelLetra.removeAll();
        jPanelLetra.repaint();
        nodoArbol=null;
    }//GEN-LAST:event_jButtonNuevoActionPerformed

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        inOrderNodo(nodoArbol);
        arbol2D.setPrincipal(nodoArbol);
        Graphics graphicsArbol=jPanelArbol.getGraphics();
        //Limpiamos el panel del arbol para actualizar el dibujo
        graphicsArbol.clearRect(10, 5, jPanelArbol.getWidth()-30, jPanelArbol.getHeight()-50);
        //Dibujamos el arbol
        arbol2D.setPrincipal(nodoArbol);
        alturaArbol=arbol2D.getAlturaArbol();
        numeroNodos=arbol2D.getNumeroNodos();
        dibujarArbol(graphicsArbol);
        //Dibujamos el plano con las letras
        Graphics graphicsPlano=jPanelLetra.getGraphics();
        graphicsPlano.clearRect(10, 5, jPanelLetra.getWidth()-10, jPanelLetra.getHeight()-20);
        dibujarPlano(graphicsPlano);
        
    }//GEN-LAST:event_jButton1ActionPerformed
     /**
      * Metodo que llena el arreglo de letras con los cuales se van a crear los ondos hoja
      */
     private void llenarLetras(){
        listaLetras.add("A");
        listaLetras.add("B");
        listaLetras.add("C");
        listaLetras.add("D");
        listaLetras.add("E");
        listaLetras.add("F");
        listaLetras.add("G");
        listaLetras.add("H");
        listaLetras.add("I");
        listaLetras.add("J");
        listaLetras.add("K");
        listaLetras.add("L");
        listaLetras.add("M");
        listaLetras.add("N");
        listaLetras.add("O");
        listaLetras.add("P");
        listaLetras.add("Q");
        listaLetras.add("R");
        listaLetras.add("S");
        listaLetras.add("T");
        listaLetras.add("U");
        listaLetras.add("V");
        listaLetras.add("W");
        listaLetras.add("X");
        listaLetras.add("Y");
        listaLetras.add("Z");
    }

    /**
     * Metodo que asigna un valor del arreglo de letras a un nuevo nodo hijo
     * @return
     */
    private String asignarValorHoja(){
        String letra=listaLetras.get(contador);
        contador++;
        return letra;
    }

    /**
     * Metodo que llena una hoja con una letra,  cuando el nodo sea null
     * @param nodo
     */
    private void llenarHojas(Nodo nodo){
        if(nodo!=null){

            llenarHojas(nodo.getIzquierda());
            llenarHojas(nodo.getDerecha());
            if(nodo.getIzquierda()==null){
               nodo.setIzquierda(new Nodo(asignarValorHoja()));
            }
            if(nodo.getDerecha()==null){
                    nodo.setDerecha(new Nodo(asignarValorHoja()));
            }
        }


    }

    /**
     * Metodo que borra todas las hojas desde la raiz
     * @param nodo
     */
    private void borrarHoja(Nodo nodo){
        if(nodo!=null){
            if(nodo.getDerecha()!=null && !(nodo.getDerecha().getDato().equals(Constantes.LINEA_HORIZONTAL) || nodo.getDerecha().getDato().equals(Constantes.LINEA_VERTICAL))){
                nodo.setDerecha(null);
            }

            if(nodo.getIzquierda()!=null && !(nodo.getIzquierda().getDato().equals(Constantes.LINEA_HORIZONTAL) || nodo.getIzquierda().getDato().equals(Constantes.LINEA_VERTICAL))){
                nodo.setIzquierda(null);
            }
            borrarHoja(nodo.getIzquierda());
            borrarHoja(nodo.getDerecha());

        }

    }

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Principal().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButtonNuevo;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JPanel jPanelArbol;
    private javax.swing.JPanel jPanelLetra;
    private javax.swing.JPanel jPanelPlano;
    private javax.swing.JTextField jTextFieldAlto;
    private javax.swing.JTextField jTextFieldAncho;
    // End of variables declaration//GEN-END:variables

}
